﻿using System;

namespace Microsoft.Xna.Framework.Graphics
{
	/// <summary>
	/// Represents an Effect parameter.
	/// </summary>
	public sealed class EffectParameter
	{
		#region Fields
		private int _columns;
		internal EffectAnnotationCollection pAnnotations;
		internal EffectParameterCollection pElementCollection;
		internal string _name;
		internal EffectParameterClass _paramClass;
		internal EffectParameterType _paramType;
		private Effect _parent;
		internal int _rows;
		internal EffectParameterCollection pParamCollection;
		private int _index;
		internal string _semantic;
		#endregion

		#region Properties
		/// <summary>
		/// Gets the collection of EffectAnnotation objects for this parameter.
		/// </summary>
		public EffectAnnotationCollection Annotations
		{
			get { return pAnnotations; }
		}

		/// <summary>
		/// Gets the number of columns in the parameter description.
		/// </summary>
		public int ColumnCount
		{
			get { return _columns; }
		}

		/// <summary>
		/// Gets the collection of effect parameters.
		/// </summary>
		public EffectParameterCollection Elements
		{
			get { return pElementCollection; }
		}

		/// <summary>
		/// Gets the name of the parameter.
		/// </summary>
		public string Name
		{
			get { return _name; }
		}

		/// <summary>
		/// Gets the class of the parameter.
		/// </summary>
		public EffectParameterClass ParameterClass
		{
			get { return _paramClass; }
		}

		/// <summary>
		/// Gets the type of the parameter.
		/// </summary>
		public EffectParameterType ParameterType
		{
			get { return _paramType; }
		}

		/// <summary>
		/// Gets the number of rows in the parameter description.
		/// </summary>
		public int RowCount
		{
			get { return _rows; }
		}

		/// <summary>
		/// Gets the semantic meaning, or usage, of the parameter.
		/// </summary>
		public string Semantic
		{
			get { return _semantic; }
		}

		/// <summary>
		/// Gets the collection of structure members.
		/// </summary>
		public EffectParameterCollection StructureMembers
		{
			get { return pParamCollection; }
		}
		#endregion

		#region Constructor
		internal EffectParameter(Effect effect, int index)
		{
			this._parent = effect;
			this._index = index;
			this.pAnnotations = new EffectAnnotationCollection(4);
			this.pParamCollection = new EffectParameterCollection(effect, 4, false);
			this.pElementCollection = new EffectParameterCollection(effect, 4, true);
		}
		#endregion

		#region Public Methods
		/// <summary>
		/// Gets the value of the EffectParameter as a Boolean.
		/// </summary>
		public bool GetValueBoolean()
		{
			if ((this._paramClass != EffectParameterClass.Scalar) && (this.pElementCollection.Count == 0))
			{
				throw new InvalidCastException();
			}

			//! TODO: if possible, implement
			return false;
		}

		/// <summary>
		/// Gets the value of the EffectParameter as an array of Boolean.
		/// </summary>
		/// <param name="count">The number of elements in the array.</param>
		public bool[] GetValueBooleanArray(int count)
		{
			if (count <= 0)
			{
				throw new ArgumentOutOfRangeException();
			}
			bool[] flagArray = new bool[count];
			if (this._paramClass != EffectParameterClass.Matrix)
			{
				//! TODO: if possible, implement
			}
			return flagArray;
		}

		/// <summary>
		/// Gets the value of the EffectParameter as an Int32.
		/// </summary>
		public int GetValueInt32()
		{
			if ((this._paramClass != EffectParameterClass.Scalar) && (this.pElementCollection.Count == 0))
			{
				throw new InvalidCastException();
			}

			//! TODO: if possible, implement
			return 0;
		}

		/// <summary>
		/// Gets the value of the EffectParameter as an array of Int32.
		/// </summary>
		/// <param name="count">The number of elements in the array.</param>
		public int[] GetValueInt32Array(int count)
		{
			if (count <= 0)
			{
				throw new ArgumentOutOfRangeException();
			}
			int[] destination = new int[count];
			if (this._paramClass != EffectParameterClass.Matrix)
			{
				//! TODO: if possible, implement
			}
			return destination;
		}

		/// <summary>
		/// Gets the value of the EffectParameter as a Matrix.
		/// </summary>
		public Matrix GetValueMatrix()
		{
			Matrix matrix = new Matrix();
			if (this.pElementCollection.Count == 0)
			{
				if (this._paramClass == EffectParameterClass.Scalar)
				{
					//! TODO: if possible, implement
					return matrix;
				}
				if (this._paramClass != EffectParameterClass.Matrix)
				{
					throw new InvalidCastException();
				}
			}
			//! TODO: if possible, implement
			return matrix;
		}

		/// <summary>
		/// Gets the value of the EffectParameter as an array of Matrix.
		/// </summary>
		/// <param name="count">The number of elements in the array.</param>
		public Matrix[] GetValueMatrixArray(int count)
		{
			int num;
			if (count <= 0)
			{
				throw new ArgumentOutOfRangeException();
			}
			if ((this._paramClass != EffectParameterClass.Matrix) || (this.pElementCollection.Count == 0))
			{
				throw new InvalidCastException();
			}
			int num2 = this.pElementCollection.Count * 0x10;
			float[] source = new float[num2];

			//! TODO: if possible, implement

			Matrix[] matrixArray = new Matrix[count];

			//! TODO: if possible, implement

			return matrixArray;
		}

		/// <summary>
		/// Gets the value of the EffectParameter as a Matrix transpose.
		/// </summary>
		public Matrix GetValueMatrixTranspose()
		{
			Matrix matrix = new Matrix();
			if (this.pElementCollection.Count == 0)
			{
				if (this._paramClass == EffectParameterClass.Scalar)
				{
					float num = default(float);// float num;

					//! TODO: if possible, implement

					matrix.M14 = num;
					matrix.M13 = num;
					matrix.M12 = num;
					matrix.M11 = num;
					matrix.M24 = num;
					matrix.M23 = num;
					matrix.M22 = num;
					matrix.M21 = num;
					matrix.M34 = num;
					matrix.M33 = num;
					matrix.M32 = num;
					matrix.M31 = num;
					matrix.M44 = num;
					matrix.M43 = num;
					matrix.M42 = num;
					matrix.M41 = num;
					return matrix;
				}
				if (this._paramClass != EffectParameterClass.Matrix)
				{
					throw new InvalidCastException();
				}
			}
			//! TODO: if possible, implement

			return matrix;
		}

		/// <summary>
		/// Gets the value of the EffectParameter as an array of Matrix transpose.
		/// </summary>
		/// <param name="count">The number of elements in the array.</param>
		public Matrix[] GetValueMatrixTransposeArray(int count)
		{
			int num;
			if (count <= 0)
			{
				throw new ArgumentOutOfRangeException();
			}
			if ((this._paramClass != EffectParameterClass.Matrix) || (this.pElementCollection.Count == 0))
			{
				throw new InvalidCastException();
			}
			int num2 = this.pElementCollection.Count * 0x10;
			float[] source = new float[num2];

			//! TODO: if possible, implement

			Matrix[] matrixArray = new Matrix[count];

			//! TODO: if possible, implement

			return matrixArray;
		}

		/// <summary>
		/// Gets the value of the EffectParameter as a Quaternion.
		/// </summary>
		public Quaternion GetValueQuaternion()
		{
			Quaternion quaternion = new Quaternion();
			if (this.pElementCollection.Count == 0)
			{
				if (this._paramClass == EffectParameterClass.Scalar)
				{
					float num = default(float); //float num;

					//! TODO: if possible, implement

					quaternion.W = num;
					quaternion.Z = num;
					quaternion.Y = num;
					quaternion.X = num;
					return quaternion;
				}
				if (this._paramClass != EffectParameterClass.Vector)
				{
					throw new InvalidCastException();
				}
				if ((this._columns != 4) || (this._rows != 1))
				{
					throw new InvalidCastException();
				}
			}
			//! TODO: if possible, implement

			return quaternion;
		}

		/// <summary>
		/// Gets the value of the EffectParameter as an array of Quaternion.
		/// </summary>
		/// <param name="count">The number of elements in the array.</param>
		public Quaternion[] GetValueQuaternionArray(int count)
		{
			if (count <= 0)
			{
				throw new ArgumentOutOfRangeException();
			}

			Quaternion[] quaternionArray = new Quaternion[count];

			//! TODO: if possible, implement

			return quaternionArray;
		}

		/// <summary>
		/// Gets the value of the EffectParameter as a Single.
		/// </summary>
		public float GetValueSingle()
		{
			float num2 = default(float);// float num2;
			if ((this._paramClass != EffectParameterClass.Scalar) && (this.pElementCollection.Count == 0))
			{
				throw new InvalidCastException();
			}

			//! TODO: if possible, implement

			return num2;
		}

		/// <summary>
		/// Gets the value of the EffectParameter as an array of Single.
		/// </summary>
		/// <param name="count">The number of elements in the array.</param>
		public float[] GetValueSingleArray(int count)
		{
			if (count <= 0)
			{
				throw new ArgumentOutOfRangeException();
			}
			float[] destination = new float[count];
			if (this._paramClass != EffectParameterClass.Matrix)
			{
				//! TODO: if possible, implement
			}
			int num21 = this._columns;
			int num20 = this._rows * num21;
			int num3 = this.pElementCollection.Count;
			if (num3 != 0)
			{
				int num13 = Math.Min(count, num3 * 0x10);

				//! TODO: if possible, implement
			}
			Matrix valueMatrix = this.GetValueMatrix();
			int num18 = Math.Min(count, num20);
			//! TODO: if possible, implement

			return destination;
		}

		/// <summary>
		/// Gets the value of the EffectParameter as an String.
		/// </summary>
		public string GetValueString()
		{
			if (this._paramType != EffectParameterType.String)
			{
				throw new InvalidCastException();
			}

			//! TODO: if possible, implement
			return String.Empty;
		}

		/// <summary>
		/// Gets the value of the EffectParameter as a Texture2D.
		/// </summary>
		public Texture2D GetValueTexture2D()
		{
			if ((this._paramType != EffectParameterType.Texture) && (this._paramType != EffectParameterType.Texture2D))
			{
				throw new InvalidCastException();
			}

			Texture2D texture = null;

			//! TODO: if possible, implement

			return texture;
		}

		/// <summary>
		/// Gets the value of the EffectParameter as a Texture3D.
		/// </summary>
		public Texture3D GetValueTexture3D()
		{
			if ((this._paramType != EffectParameterType.Texture) && (this._paramType != EffectParameterType.Texture3D))
			{
				throw new InvalidCastException();
			}

			Texture3D texture = null;

			//! TODO: if possible, implement

			return texture;
		}

		/// <summary>
		/// Gets the value of the EffectParameter as a TextureCube.
		/// </summary>
		public TextureCube GetValueTextureCube()
		{
			if ((this._paramType != EffectParameterType.Texture) && (this._paramType != EffectParameterType.TextureCube))
			{
				throw new InvalidCastException();
			}

			TextureCube cube = null;

			//! TODO: if possible, implement

			return cube;
		}

		/// <summary>
		/// Gets the value of the EffectParameter as a Vector2.
		/// </summary>
		public Vector2 GetValueVector2()
		{
			Vector2 vector = new Vector2();
			if (this.pElementCollection.Count == 0)
			{
				if (this._paramClass == EffectParameterClass.Scalar)
				{
					float num = default(float);// float num3;

					//! TODO: if possible, implement

					vector.X = num;
					vector.Y = num;
					return vector;
				}
				if (this._paramClass != EffectParameterClass.Vector)
				{
					throw new InvalidCastException();
				}
				if ((this._columns != 2) || (this._rows != 1))
				{
					throw new InvalidCastException();
				}
			}

			//! TODO: if possible, implement
			return vector;
		}

		/// <summary>
		/// Gets the value of the EffectParameter as an array of Vector2.
		/// </summary>
		/// <param name="count">The number of elements in the array.</param>
		public Vector2[] GetValueVector2Array(int count)
		{
			if (count <= 0)
			{
				throw new ArgumentOutOfRangeException();
			}

			//! TODO: if possible, implement

			Vector2[] vectorArray = new Vector2[count];

			//! TODO: if possible, implement

			return vectorArray;
		}

		/// <summary>
		/// Gets the value of the EffectParameter as a Vector3.
		/// </summary>
		public Vector3 GetValueVector3()
		{
			Vector3 vector = new Vector3();
			if (this.pElementCollection.Count == 0)
			{
				if (this._paramClass == EffectParameterClass.Scalar)
				{
					float num = default(float);// float num;

					//! TODO: if possible, implement

					vector.X = num;
					vector.Y = num;
					vector.Z = num;
					return vector;
				}
				if (this._paramClass != EffectParameterClass.Vector)
				{
					throw new InvalidCastException();
				}
				if ((this._columns != 3) || (this._rows != 1))
				{
					throw new InvalidCastException();
				}
			}

			//! TODO: if possible, implement

			return vector;
		}

		/// <summary>
		/// Gets the value of the EffectParameter as an array of Vector3.
		/// </summary>
		/// <param name="count">The number of elements in the array.</param>
		public Vector3[] GetValueVector3Array(int count)
		{
			if (count <= 0)
			{
				throw new ArgumentOutOfRangeException();
			}

			//! TODO: if possible, implement

			Vector3[] vectorArray = new Vector3[count];

			//! TODO: if possible, implement

			return vectorArray;
		}

		/// <summary>
		/// Gets the value of the EffectParameter as a Vector4.
		/// </summary>
		public Vector4 GetValueVector4()
		{
			Vector4 vector = new Vector4();
			if (this.pElementCollection.Count == 0)
			{
				if (this._paramClass == EffectParameterClass.Scalar)
				{
					float num = default(float);// float num;

					//! TODO: if possible, implement

					vector.X = num;
					vector.Y = num;
					vector.Z = num;
					vector.W = num;
					return vector;
				}
				if (this._paramClass != EffectParameterClass.Vector)
				{
					throw new InvalidCastException();
				}
				if ((this._columns != 4) || (this._rows != 1))
				{
					throw new InvalidCastException();
				}
			}

			//! TODO: if possible, implement

			return vector;
		}

		/// <summary>
		/// Gets the value of the EffectParameter as an array of Vector4.
		/// </summary>
		/// <param name="count">The number of elements in the array.</param>
		public Vector4[] GetValueVector4Array(int count)
		{
			if (count <= 0)
			{
				throw new ArgumentOutOfRangeException();
			}
			//! TODO: if possible, implement

			Vector4[] vectorArray = new Vector4[count];
			//! TODO: if possible, implement
			return vectorArray;
		}

		/// <summary>
		/// Sets the value of the EffectParameter.
		/// </summary>
		/// <param name="value">The value to assign to the EffectParameter.</param>
		public void SetValue(Quaternion[] value)
		{
			if ((this._paramClass != EffectParameterClass.Vector) || (this.pElementCollection.Count == 0))
			{
				throw new InvalidCastException();
			}
			if ((value != null) && (value.Length > 0))
			{
				//! TODO: if possible, implement
			}
			else
			{
				//! TODO: if possible, implement
			}
		}

		/// <summary>
		/// Sets the value of the EffectParameter.
		/// </summary>
		/// <param name="value">The value to assign to the EffectParameter.</param>
		public void SetValue(Vector3[] value)
		{
			if ((this._paramClass != EffectParameterClass.Vector) || (this.pElementCollection.Count == 0))
			{
				throw new InvalidCastException();
			}
			if ((value != null) && (value.Length > 0))
			{
				//! TODO: if possible, implement
			}
			else
			{
				//! TODO: if possible, implement
			}
		}

		/// <summary>
		/// Sets the value of the EffectParameter.
		/// </summary>
		/// <param name="value">The value to assign to the EffectParameter.</param>
		public void SetValue(Quaternion value)
		{
			if (this.pElementCollection.Count != 0)
			{
				throw new InvalidCastException();
			}
			if ((this._paramClass != EffectParameterClass.Vector) || (this._columns != 4) || (this._rows != 1))
			{
				throw new InvalidCastException();
			}

			//! TODO: if possible, implement
		}

		/// <summary>
		/// Sets the value of the EffectParameter.
		/// </summary>
		/// <param name="value">The value to assign to the EffectParameter.</param>
		public void SetValue(Vector2 value)
		{
			if (this.pElementCollection.Count != 0)
			{
				throw new InvalidCastException();
			}
			if ((this._paramClass != EffectParameterClass.Vector) || (this._columns != 2) || (this._rows != 1))
			{
				throw new InvalidCastException();
			}

			//! TODO: if possible, implement
		}

		/// <summary>
		/// Sets the value of the EffectParameter.
		/// </summary>
		/// <param name="value">The value to assign to the EffectParameter.</param>
		public void SetValue(Vector3 value)
		{
			if (this.pElementCollection.Count != 0)
			{
				throw new InvalidCastException();
			}
			if ((this._paramClass != EffectParameterClass.Vector) || (this._columns != 3) || (this._rows != 1))
			{
				throw new InvalidCastException();
			}

			//! TODO: if possible, implement
		}

		/// <summary>
		/// Sets the value of the EffectParameter.
		/// </summary>
		/// <param name="value">The value to assign to the EffectParameter.</param>
		public void SetValue(Vector4 value)
		{
			if (this.pElementCollection.Count != 0)
			{
				throw new InvalidCastException();
			}
			if ((this._paramClass != EffectParameterClass.Vector) || (this._columns != 4) || (this._rows != 1))
			{
				throw new InvalidCastException();
			}

			//! TODO: if possible, implement
		}

		/// <summary>
		/// Sets the value of the EffectParameter.
		/// </summary>
		/// <param name="value">The value to assign to the EffectParameter.</param>
		public void SetValue(bool value)
		{
			if (this.pElementCollection.Count != 0)
			{
				throw new InvalidCastException();
			}
			if ((this._paramClass == EffectParameterClass.Vector) && (this._rows == 1))
			{
				//! TODO: if possible, implement
			}

			//! TODO: if possible, implement
		}

		/// <summary>
		/// Sets the value of the EffectParameter.
		/// </summary>
		/// <param name="value">The value to assign to the EffectParameter.</param>
		public void SetValue(Matrix[] value)
		{
			if (this._paramClass == EffectParameterClass.Matrix)
			{
				if ((value.Length <= this.pElementCollection.Count) && (this.pElementCollection.Count != 0))
				{
					//! TODO: if possible, implement
				}
			}

			//! TODO: if possible, implement
		}

		/// <summary>
		/// Sets the value of the EffectParameter.
		/// </summary>
		/// <param name="value">The value to assign to the EffectParameter.</param>
		public void SetValue(int value)
		{
			if (this.pElementCollection.Count != 0)
			{
				throw new InvalidCastException();
			}
			if ((this._paramClass == EffectParameterClass.Vector) && (this._rows == 1))
			{
				//! TODO: if possible, implement
			}

			//! TODO: if possible, implement
		}

		/// <summary>
		/// Sets the value of the EffectParameter.
		/// </summary>
		/// <param name="value">The value to assign to the EffectParameter.</param>
		public void SetValue(Vector2[] value)
		{
			if ((this._paramClass != EffectParameterClass.Vector) || (this.pElementCollection.Count == 0))
			{
				throw new InvalidCastException();
			}
			if ((value != null) && (value.Length > 0))
			{
				//! TODO: if possible, implement
			}

			//! TODO: if possible, implement
		}

		/// <summary>
		/// Sets the value of the EffectParameter.
		/// </summary>
		/// <param name="value">The value to assign to the EffectParameter.</param>
		public void SetValue(float value)
		{
			if (this.pElementCollection.Count != 0)
			{
				throw new InvalidCastException();
			}
			if ((this._paramClass == EffectParameterClass.Vector) && (this._rows == 1))
			{
				//! TODO: if possible, implement
			}

			//! TODO: if possible, implement
		}

		/// <summary>
		/// Sets the value of the EffectParameter.
		/// </summary>
		/// <param name="value">The value to assign to the EffectParameter.</param>
		public void SetValue(Vector4[] value)
		{
			if ((this._paramClass != EffectParameterClass.Vector) || (this.pElementCollection.Count == 0))
			{
				throw new InvalidCastException();
			}
			if ((value != null) && (value.Length > 0))
			{
				//! TODO: if possible, implement
			}

			//! TODO: if possible, implement
		}

		/// <summary>
		/// Sets the value of the EffectParameter.
		/// </summary>
		/// <param name="value">The value to assign to the EffectParameter.</param>
		public void SetValue(Matrix value)
		{
			if ((this._paramClass != EffectParameterClass.Matrix) || (this.pElementCollection.Count != 0))
			{
				throw new InvalidCastException();
			}
			//! TODO: if possible, implement
		}

		/// <summary>
		/// Sets the value of the EffectParameter.
		/// </summary>
		/// <param name="value">The value to assign to the EffectParameter.</param>
		public void SetValue(bool[] value)
		{
			if ((this._paramClass != EffectParameterClass.Scalar) && (this._paramClass != EffectParameterClass.Vector) && (this._paramClass != EffectParameterClass.Matrix))
			{
				throw new InvalidCastException();
			}
			if (value != null)
			{
				int length = value.Length;
				if (length > 0)
				{
					if (this._paramClass == EffectParameterClass.Matrix)
					{
						int num24 = this._columns;
						int num23 = this._rows * num24;
						int count = this.pElementCollection.Count;
						if (count == 0)
						{
							Matrix valueMatrix = this.GetValueMatrix();
							int num19 = Math.Min(value.Length, num23);

							//! TODO: if possible, implement
						}

						//! TODO: if possible, implement
					}

					//! TODO: if possible, implement
				}

				//! TODO: if possible, implement
			}

			//! TODO: if possible, implement
		}

		/// <summary>
		/// Sets the value of the EffectParameter.
		/// </summary>
		/// <param name="value">The value to assign to the EffectParameter.</param>
		public void SetValue(Texture value)
		{
			if (value != null)
			{
				//! TODO: if possible, implement
			}
			if ((this._paramType != EffectParameterType.Texture) && (this._paramType != EffectParameterType.Texture1D) && (this._paramType != EffectParameterType.Texture2D) && (this._paramType != EffectParameterType.Texture3D) && (this._paramType != EffectParameterType.TextureCube))
			{
				throw new InvalidCastException();
			}
			//! TODO: if possible, implement
		}

		/// <summary>
		/// Sets the value of the EffectParameter.
		/// </summary>
		/// <param name="value">The value to assign to the EffectParameter.</param>
		public void SetValue(string value)
		{
			if (this._paramType != EffectParameterType.String)
			{
				throw new InvalidCastException();
			}

			//! TODO: if possible, implement
		}

		/// <summary>
		/// Sets the value of the EffectParameter.
		/// </summary>
		/// <param name="value">The value to assign to the EffectParameter.</param>
		public void SetValue(int[] value)
		{
			if ((this._paramClass != EffectParameterClass.Scalar) && (this._paramClass != EffectParameterClass.Vector) && (this._paramClass != EffectParameterClass.Matrix))
			{
				throw new InvalidCastException();
			}
			if ((value != null) && (value.Length > 0))
			{
				//! TODO: if possible, implement
			}
		}

		/// <summary>
		/// Sets the value of the EffectParameter.
		/// </summary>
		/// <param name="value">The value to assign to the EffectParameter.</param>
		public void SetValue(float[] value)
		{
			if ((this._paramClass != EffectParameterClass.Scalar) && (this._paramClass != EffectParameterClass.Vector) && (this._paramClass != EffectParameterClass.Matrix))
			{
				throw new InvalidCastException();
			}
			if ((value != null) && (value.Length > 0))
			{
				//! TODO: if possible, implement
			}
		}

		/// <summary>
		/// Sets the value of the EffectParameter to the transpose of a Matrix.
		/// </summary>
		/// <param name="value">The value.</param>
		public void SetValueTranspose(Matrix[] value)
		{
			if (this._paramClass == EffectParameterClass.Matrix)
			{
				//EffectParameterCollection pElementCollection = this.pElementCollection;
				if ((value.Length <= pElementCollection.Count) && (this.pElementCollection.Count != 0))
				{

				}
			}
			throw new InvalidCastException();
		}

		/// <summary>
		/// Sets the value of the EffectParameter to the transpose of a Matrix.
		/// </summary>
		/// <param name="value">The value.</param>
		public void SetValueTranspose(Matrix value)
		{
			if ((this._paramClass != EffectParameterClass.Matrix) || (this.pElementCollection.Count != 0))
			{
				throw new InvalidCastException();
			}
			//! TODO: if possible, implement
		}
		#endregion
	}
}
